package at.tugraz.ist.catroid.physics;

import java.util.HashMap;
import org.jbox2d.collision.AABB;  
import org.jbox2d.collision.Bound;
import org.jbox2d.collision.CircleDef;  
import org.jbox2d.collision.PolygonDef;
import org.jbox2d.common.Vec2;  
import org.jbox2d.dynamics.Body;  
import org.jbox2d.dynamics.BodyDef;  
import org.jbox2d.dynamics.World;
import at.tugraz.ist.catroid.stage.StageActivity;
import at.tugraz.ist.catroid.utils.Position;
import android.util.Log;

public class CatroidPhysics {
	
	public boolean isPhyCreated = false;
	

    private BodyDef groundBodyDef;
    private PolygonDef groundShapeDef;
	private AABB worldAABB;
	private World world;
	private Body groundBody;
	
	//TODO: better bodies list
	private int totalbodies = 0;
	private HashMap<Integer, Body> bodies = new HashMap<Integer, Body>();
	
	private static float timeStep = (float)0.15;
    private int iterations = 3;
    private int pxPerM = 30; // how many pixels is in meter

	public void createWorld() {
		if (isPhyCreated)
			return;
		init();
		isPhyCreated = true;
	}
	
	private void init() {
		 // Create world boundaries
       worldAABB = new AABB();
       worldAABB.lowerBound.set(new Vec2((float) -50.0, (float) -50.0));
       worldAABB.upperBound.set(new Vec2((float) StageActivity.SCREEN_WIDTH + 50, (float) StageActivity.SCREEN_HEIGHT + 50));

       // Create gravity
       Vec2 gravity = new Vec2((float) 0.0, (float) -10.0);
       boolean doSleep = true;
       world = new World(worldAABB, gravity, true);
       
       //Create ground box
       groundBodyDef = new BodyDef();
       groundBodyDef.position.set(new Vec2((float) -50.0, (float) -50.0));
       groundBody = world.createBody(groundBodyDef);
       groundShapeDef = new PolygonDef();
       groundShapeDef.setAsBox((float)StageActivity.SCREEN_WIDTH, (float) 50.0);
       groundShapeDef.density = (float)0.1;
       groundBody.createShape(groundShapeDef);
       Log.d("List", "world created");

	}
	
	public int addBody(int x, int y, int w, int h, int density) {
		BodyDef b = new BodyDef();
		totalbodies++;
		y +=w;
		Log.d("phy", "Body created at: " + x + " " +  y);
		x = (StageActivity.SCREEN_WIDTH - x);
		//hmmm...  terrible coord transformation, I can do better :/
		//TODO fix it
		y = (StageActivity.SCREEN_HEIGHT - y) - 25;
		b.position.set((float)x, (float)y);
		Body body = null;
		PolygonDef s = new PolygonDef();
		s.setAsBox((float) w/2, (float) h/2, new Vec2((float) w/2, (float) h/2), 0);
		s.density = (float)density;
		s.restitution = 0.05f;
		body = world.createBody(b);
		body.createShape(s);
		body.setMassFromShapes();
		Log.d("List", "Create body" + totalbodies + " " + 	density);
		bodies.put(totalbodies, body);
		return totalbodies;
	}
	
	//returns object position
	public Position getPos(int id){
		Body body = bodies.get(id);
		Vec2 pos = body.getPosition();
		Log.d("List", "Object " + id + " New x" + pos.x + " New y" + pos.y + " rot " + (int)Math.toDegrees(body.getAngle()));
		//Log.d("List", "Ground" + groundBody.getPosition().y);
		return new Position(StageActivity.SCREEN_WIDTH -(int)pos.x, StageActivity.SCREEN_HEIGHT - (int)pos.y, (int)Math.toDegrees(body.getAngle()));
	}
	
	public void destroyBody(int id){
		world.destroyBody(bodies.get(id));
	}
	
	
    public void update() {
    	Log.d("phy", "UPDATE");
        world.step(timeStep, iterations);
    }
}
